From: Colin Walters Date: Fri, 2 Oct 2009 19:55:55 +0000 (-0400) Subject: Disconnect from window user time notifications, only sort when mapped X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~10772 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=4bdd40911ff8c42df1ab6681feb91b89fe0281f5;p=gnome-shell.git Disconnect from window user time notifications, only sort when mapped Before we were badly leaking AppIcons by not disconnecting from the window signal handlers when our actor got destroyed. This caused us to repeatedly re-sort the windows for each AppIcon that had ever been displayed with obvious bad consequences. Besides simply chaining the signals to the lifetime of the AppIcon actor, we also only do the sorting if we're mapped. This decreases the amount of work to do in the not-mapped case. https://bugzilla.gnome.org/show_bug.cgi?id=597120 --- diff --git a/js/ui/appIcon.js b/js/ui/appIcon.js index 5585eb060..d7dbd7726 100644 --- a/js/ui/appIcon.js +++ b/js/ui/appIcon.js @@ -70,13 +70,21 @@ AppIcon.prototype = { reactive: true }); this.actor._delegate = this; this.highlight_border_color = APPICON_DEFAULT_BORDER_COLOR; + this._signalIds = []; + // Note, we don't presently update the window list dynamically here; this actor + // gets destroyed and recreated by AppWell, and in alt-tab the whole thing is + // created each time this.windows = Shell.AppMonitor.get_default().get_windows_for_app(this.appInfo.get_id()); for (let i = 0; i < this.windows.length; i++) { - this.windows[i].connect('notify::user-time', Lang.bind(this, this._resortWindows)); + let sigId = this.windows[i].connect('notify::user-time', Lang.bind(this, this._resortWindows)); + this._signalIds.push([this.windows[i], sigId]); } this._resortWindows(); + this.actor.connect('destroy', Lang.bind(this, this._destroy)); + this.actor.connect('notify::mapped', Lang.bind(this, this._onMappedChanged)); + if (this._menuType != MenuType.NONE) { this.actor.connect('button-press-event', Lang.bind(this, this._updateMenuOnButtonPress)); this.actor.connect('notify::hover', Lang.bind(this, this._updateMenuOnHoverChanged)); @@ -167,7 +175,26 @@ AppIcon.prototype = { } }, + _destroy: function() { + for (let i = 0; i < this._signalIds.length; i++) { + let [obj, sigId] = this._signalIds[i]; + obj.disconnect(sigId); + } + }, + + _onMappedChanged: function() { + let mapped = this.actor.mapped; + if (mapped && this._windowSortStale) + this._resortWindows(); + }, + _resortWindows: function() { + let mapped = this.actor.mapped; + if (!mapped) { + this._windowSortStale = true; + return; + } + this._windowSortStale = false; this.windows.sort(function (a, b) { let activeWorkspace = global.screen.get_active_workspace(); let wsA = a.get_workspace() == activeWorkspace;